import { useUserStore } from "@/stores/useUserStore";
import { WebSocketMessageType, type WebSocketMessage } from "@/types";

export class WebSocketClient {
  private ws: WebSocket | null = null;
  private readonly url: string;
  private reconnectAttempts = 0; // 重连次数
  private readonly maxReconnectAttempts = 5;
  private readonly reconnectInterval = 3000; // 重连间隔，单位毫秒
  private heartbeatInterval: number | null = null;
  private readonly heartbeatTimer = 30000; // 心跳间隔，单位毫秒
  private messageHandlers: Map<WebSocketMessageType, Function[]> = new Map();

  constructor(baseUrl: string) {
    this.url = baseUrl;
  }

  /**
   * 连接WebSocket
   */
  public connect(): void {
    const userStore = useUserStore();
    const token = userStore.token;

    if (!token) {
      console.error("No token available");
      return;
    }

    try {
      // 添加token作为查询参数
      const wsUrl = `${this.url}?token=${token}`;
      this.ws = new WebSocket(wsUrl);

      this.ws.onopen = this.handleOpen.bind(this); // 连接成功
      this.ws.onmessage = this.handleMessage.bind(this); // 收到消息
      this.ws.onclose = this.handleClose.bind(this); // 连接关闭
      this.ws.onerror = this.handleError.bind(this); // 连接错误
    } catch (error) {
      console.error("WebSocket connection error:", error);
      this.reconnect();
    }
  }

  /**
   * 断开WebSocket连接
   */
  public disconnect(): void {
    if (this.ws) {
      this.stopHeartbeat(); // 停止心跳检测
      this.ws.close(); // 关闭WebSocket连接
      this.ws = null; // 将WebSocket对象设置为null
    }
  }

  /**
   * 重新连接
   */
  private reconnect(): void {
    if (this.reconnectAttempts >= this.maxReconnectAttempts) {
      console.error("Max reconnection attempts reached");
      return;
    }

    this.reconnectAttempts++;
    console.log(
      `Attempting to reconnect... (${this.reconnectAttempts}/${this.maxReconnectAttempts})`
    );

    setTimeout(() => {
      this.connect();
    }, this.reconnectInterval);
  }

  /**
   * 开始心跳检测
   */
  private startHeartbeat(): void {
    this.heartbeatInterval = window.setInterval(() => {
      console.log("准备发送心跳消息");
      this.sendHeartbeat(); // 发送心跳消息
    }, this.heartbeatTimer);
  }

  /**
   * 停止心跳检测
   */
  private stopHeartbeat(): void {
    if (this.heartbeatInterval) {
      clearInterval(this.heartbeatInterval); // 清除心跳检测
      this.heartbeatInterval = null; // 将心跳检测设置为null
    }
  }

  /**
   * 发送心跳消息
   */
  private sendHeartbeat(): void {
    if (this.ws && this.ws.readyState === WebSocket.OPEN) {
      const heartbeatMessage: WebSocketMessage = {
        type: WebSocketMessageType.HEARTBEAT,
        data: "ping",
        timestamp: Date.now(),
      };
      this.ws.send(JSON.stringify(heartbeatMessage));
    }
  }

  /**
   * 添加消息处理器
   */
  public addMessageHandler(
    type: WebSocketMessageType,
    handler: Function
  ): void {
    const handlers = this.messageHandlers.get(type) || []; //获取对应的消息处理器
    handlers.push(handler); //添加处理器
    this.messageHandlers.set(type, handlers); //设置处理器
  }

  /**
   * 移除消息处理器
   */
  public removeMessageHandler(
    type: WebSocketMessageType,
    handler: Function
  ): void {
    const handlers = this.messageHandlers.get(type); //获取对应的消息处理器
    if (handlers) {
      const index = handlers.indexOf(handler); //获取处理器的索引
      if (index !== -1) {
        handlers.splice(index, 1); //移除处理器
      }
    }
  }

  /**
   * 处理WebSocket打开连接
   */
  private handleOpen(): void {
    console.log("WebSocket connected");
    this.reconnectAttempts = 0;
    this.startHeartbeat();
  }

  /**
   * 处理WebSocket消息
   */
  private handleMessage(event: MessageEvent): void {
    try {
      const message: WebSocketMessage = JSON.parse(event.data); // 解析消息
      console.log("收到来自后端的WebSocket消息：", message);
      // 在 handleMessage 方法中
      const handlers = this.messageHandlers.get(message.type); // 获取消息处理器

      if (handlers) {
        handlers.forEach((handler) => handler(message)); //执行对应的消息处理器
      }
    } catch (error) {
      console.error("Error handling message:", error);
    }
  }

  /**
   * 处理WebSocket关闭连接
   */
  private handleClose(): void {
    console.log("WebSocket disconnected"); // 连接关闭
    this.stopHeartbeat(); // 停止心跳检测
    this.reconnect(); // 重新连接
  }

  /**
   * 处理WebSocket错误
   */
  private handleError(error: Event): void {
    console.error("WebSocket error:", error);
    this.disconnect();
    this.reconnect();
  }

  /**
   * 发送消息
   */
  public sendMessage(message: WebSocketMessage): void {
    console.log("准备发送WebSocket消息:", message);
    if (!this.ws || this.ws.readyState !== WebSocket.OPEN) {
      console.error("WebSocket未连接，尝试重新连接...");
      this.connect();
      // 等待连接成功后重试发送
      const retryInterval = setInterval(() => {
        if (this.ws?.readyState === WebSocket.OPEN) {
          clearInterval(retryInterval);
          console.log("WebSocket重连成功，发送消息:", message);
          this.ws.send(JSON.stringify(message));
        }
      }, 1000);
      // 10秒后如果还没连接成功就放弃
      setTimeout(() => {
        clearInterval(retryInterval);
        console.error("WebSocket重连超时，消息发送失败");
      }, 10000);
      return;
    }
    this.ws.send(JSON.stringify(message));
  }
}

// 创建WebSocket客户端单例
const wsClient = new WebSocketClient(`${import.meta.env.VITE_WS_URL}/ws/chat`);

export default wsClient; // 导出WebSocket客户端单例
